1 : <?php
2 : /*--------------------------------------------------------------------------+
3 : This file is part of eStudy.
4 : suchmaschine/classes/class.pluginzip.inc.php
5 : - Modulgruppe: Suche
6 : - Beschreibung: In dieser Datei wird die Klasse PluginZip implementiert.
7 : - Version: 0.2 01/17/08
8 : - Autor(en): Jörg Rieger
9 : +---------------------------------------------------------------------------+
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or any later version.
14 : +---------------------------------------------------------------------------+
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 : +--------------------------------------------------------------------------*/
23 :
24 1 : global $settings;
25 :
26 : /**
27 : * Path to Root falls nicht gesetzt
28 : */
29 1 : if ( !defined('PATH_TO_ROOT') ) {
30 0 : define("PATH_TO_ROOT", "../../");
31 :
32 0 : require_once('class.iindexer.inc.php');
33 0 : require_once('class.indexer.inc.php');
34 :
35 0 : }
36 :
37 1 : if ( !defined('TMP_DIR') )
38 1 : define('TMP_DIR', PATH_TO_ROOT . $settings['upload_path'] . 'such_tmp/');
39 :
40 : /**
41 : * Klasse PluginZip
42 : *
43 : * @package eStudy.Suchmaschine
44 : * @version 0.1 01/08/08
45 : * @author Jörg Rieger
46 : */
47 1 : class PluginZip extends Indexer {
48 : private $za;
49 :
50 : /**
51 : * Kontruktor
52 : *
53 : * @access public
54 : */
55 : public function __construct() {
56 : // PHP muss mit --enable-zip komipiliert worden sein
57 0 : if (class_exists('ZipArchive')) {
58 0 : $this->name = 'ZIP';
59 :
60 0 : $this->fileExt = array("zip",
61 0 : "sxw", // OpenOffice 1.x - Textdokument
62 0 : "stw", // OpenOffice 1.x - Textdokumentvorlage
63 0 : "sxc", // OpenOffice 1.x - Tabellendokument
64 0 : "stc", // OpenOffice 1.x - Tabellendokumentvorlage
65 0 : "sxi", // OpenOffice 1.x - Präsentation
66 0 : "sti", // OpenOffice 1.x - Präsentationsvorlage
67 0 : "odt", // OpenOffice 2.x - Textdokument
68 0 : "ott", // OpenOffice 2.x - Textdokumentvorlage
69 0 : "ods", // OpenOffice 2.x - Tabellendokument
70 0 : "ots", // OpenOffice 2.x - Tabellendokumentvorlage
71 0 : "odp", // OpenOffice 2.x - Präsentation
72 : "odt" // OpenOffice 2.x - Präsentationsvorlage
73 0 : );
74 :
75 0 : $this->za = new ZipArchive();
76 0 : }
77 : else {
78 0 : $this->name = 'Void';
79 0 : $this->fileExt = array();
80 : }
81 0 : }
82 :
83 : /**
84 : * Öffnen der Datei
85 : *
86 : * @access public
87 : */
88 : public function open( $fileName ) {
89 0 : if ( !file_exists($fileName) )
90 0 : throw new Exception('Datei ' . $fileName . ' existiert nicht');
91 :
92 0 : if ( $this->za->open(realpath($fileName)) !== true )
93 0 : throw new Exception('Zip Datei ' . $fileName . ' konnte nicht geöffnet werden');
94 0 : }
95 :
96 : /**
97 : * Zurückgeben des Inhalts
98 : *
99 : * @access public
100 : */
101 : public function getContent() {
102 : // Falls keine Dateien im Zip oder zu viele Dateien (null bomb)
103 0 : if ( $this->za->numFiles < 1 || $this->za->numFiles > 10000 )
104 0 : return null;
105 :
106 : // Mögliche OS Abhängigkeiten
107 0 : $freeSpace = disk_free_space( PATH_TO_ROOT );
108 0 : $zaSize = $this->calculateSize();
109 :
110 : // Nach dem entpacken müssen noch mind. 20 MB freier Plattenplatz zur Verfügung stehen
111 0 : if ( ($freeSpace - $zaSize < 20971520))
112 0 : throw new Exception('Nicht genügend freier Festplattenspeicher');
113 :
114 : // Zip entpacken
115 0 : $this->extractZip();
116 :
117 : // In TMP_DIR die entpackten Dateien indexieren, erhählt gesamten Inhalt als String
118 0 : return $this->indexTmpFiles();
119 : }
120 :
121 : /**
122 : * Schliessen der Datei
123 : *
124 : * @access public
125 : */
126 : public function close() {
127 0 : $this->za->close();
128 0 : }
129 :
130 : /**
131 : * Temporäre Dateien entfernen
132 : *
133 : * @access public
134 : */
135 : public function cleanup() {
136 0 : if ( !is_dir(TMP_DIR) )
137 0 : return true;
138 :
139 0 : $this->deltree(TMP_DIR);
140 0 : }
141 :
142 :
143 : /**
144 : * Zip entpacken
145 : *
146 : * @access proteced
147 : * @return
148 : */
149 : protected function extractZip() {
150 0 : $this->createTempDir();
151 0 : $this->za->extractTo(TMP_DIR);
152 0 : }
153 :
154 : /**
155 : * Datei Endung ermitteln
156 : *
157 : * @access proteced
158 : * @return string
159 : */
160 : protected function getExtension( $fileName ) {
161 0 : $pathParts = pathinfo($fileName);
162 :
163 0 : return (isset($pathParts['extension']) ? $pathParts['extension'] : '');
164 : }
165 :
166 : /**
167 : * Temporäres Verzeichnis erzeugen
168 : *
169 : * @access proteced
170 : * @return string
171 : */
172 : protected function createTempDir() {
173 0 : if ( is_dir(TMP_DIR) )
174 0 : $this->cleanup();
175 :
176 0 : mkdir(TMP_DIR, 0700);
177 0 : }
178 :
179 : /**
180 : * Rekursives Löschen eins Verzeichnisses inkl. der darin enthaltenen Dateien
181 : *
182 : * @access proteced
183 : * @param $f - Verzeichnis
184 : * @return
185 : */
186 : protected function deltree( $f ) {
187 0 : if( is_dir($f) ) {
188 0 : foreach( scandir($f) as $item ) {
189 0 : if( !strcmp($item, '.') || !strcmp($item, '..') )
190 0 : continue;
191 :
192 0 : $this->deltree( $f . "/" . $item );
193 0 : }
194 :
195 0 : rmdir($f);
196 0 : }
197 : else
198 0 : unlink($f);
199 0 : }
200 :
201 : /**
202 : * Berechnet den Speicherplatz Bedarf des entpackten Zips
203 : *
204 : * @access proteced
205 : * @param $f - Verzeichnis
206 : * @return int
207 : */
208 : protected function calculateSize() {
209 0 : $zaSize = 0;
210 :
211 0 : for ( $i = 0; $i < $this->za->numFiles; $i++ ) {
212 : // Enthält alle Zip-Informationen über die archivierten Dateien
213 0 : $array = $this->za->statIndex($i);
214 :
215 0 : $zaSize += $array['size'];
216 0 : }
217 :
218 0 : return $zaSize;
219 : }
220 :
221 : /**
222 : * Rekursives durchgehen des TMP_DIR Verzeichnisses
223 : *
224 : * @access proteced
225 : * @return string
226 : */
227 : protected function indexTmpFiles() {
228 0 : $content = '';
229 :
230 0 : $sc = new IndexerStrategy();
231 0 : $fileTypes = $sc->getFileTypes();
232 :
233 0 : $files = $this->getRecursiveDirectoryList(TMP_DIR);
234 :
235 0 : foreach( $files as $file) {
236 0 : $ext = $this->getExtension($file);
237 :
238 0 : if ( array_key_exists($ext, $fileTypes) )
239 0 : $sc->usePlugin($fileTypes[$this->getExtension($file)]);
240 : else
241 0 : $sc->usePlugin('');
242 :
243 0 : $sc->open($file);
244 0 : $content .= $sc->getContent() . ' ';
245 0 : $sc->close();
246 0 : $sc->cleanup();
247 :
248 0 : }
249 :
250 0 : return $content;
251 : }
252 :
253 :
254 : /**
255 : * Rekursives durchgehen des TMP_DIR Verzeichnisses
256 : *
257 : * @access proteced
258 : * @return array
259 : */
260 : public function getRecursiveDirectoryList( $startDir ) {
261 0 : $files = array ();
262 :
263 0 : if (is_dir($startDir)) {
264 0 : $fh = opendir($startDir);
265 :
266 0 : while (($file = readdir($fh)) !== false) {
267 0 : if (strcmp($file, '.') == 0 || strcmp($file, '..') == 0)
268 0 : continue;
269 :
270 0 : $filepath = $startDir . '/' . $file;
271 :
272 0 : if (is_dir($filepath))
273 0 : $files = array_merge($files, $this->getRecursiveDirectoryList($filepath));
274 : else
275 0 : array_push($files, $filepath);
276 0 : }
277 :
278 0 : closedir($fh);
279 0 : }
280 : else
281 0 : $files = false;
282 :
283 0 : return $files;
284 : }
285 :
286 : }
|